package com.nwpu.coursesupport.controller;

import com.nwpu.coursesupport.entity.bean.Context;
import com.nwpu.coursesupport.entity.bean.JSONResult;
import com.nwpu.coursesupport.entity.bean.Setting;
import com.nwpu.coursesupport.tool.JSONUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class AbstractController {

    protected static Logger logger = LoggerFactory.getLogger(AbstractController.class);
	@Autowired
	private Setting setting;

	public JSONResult invokeService(String namespace, String name) {
		return invokeService(namespace, name, null);
	}

	/**
	 *
	 * @param namespace
	 * @param name
	 * @param param
	 * @return
	 */
	public JSONResult invokeService(String namespace, String name, String param) {
		JSONResult result=new JSONResult();
		result.fail();
		if (name == null) {
			logger.error("service的name名为空");
			return result.fail("服务端调用失败");
		}
		if (param == null) {
			param = "{}";
		}
		JSONResult rst = invokeLocal(namespace, name, param);
		if (rst == null) {
			rst = result;
			logger.error("invokeLocal返回JSONResult为空");
			rst.fail("数据出错");
		}
		return rst;
	}

	private JSONResult invokeLocal(String namespace, String name, String param) {
		if (namespace == null) {
			return null;
		}

		String serviceName = namespace.substring(0, 1).toLowerCase() + namespace.substring(1) + "Service";
		Object service = Context.getBean(serviceName);
		if (service == null) {
			return null;
		}
		if (param == null) {
			param = "{}";
		}

		Method method = null;
		for (Method m : service.getClass().getDeclaredMethods()) {
			if (m.getName().equals(name)) {
				method = m;
				break;
			}
		}
		JSONResult jsonResult = new JSONResult();
		if (method == null) {
			logger.error("找不到对应的Service方法");
			return jsonResult.fail("服务端调用失败");
		}
		List<Object> args = new ArrayList<Object>();
		try {

			for (Class<?> clazz : method.getParameterTypes()) {

				Object p = JSONUtils.json2pojo(param, clazz);
				if (p == null) {
					logger.error("参数转换失败");
					return jsonResult.fail("参数转换失败");
				}
				args.add(p);
			}
			//这种情况默认只要一个参数
			if (method.getParameterTypes().length == 0) {
				jsonResult = (JSONResult) method.invoke(service);
			} else if (method.getParameterTypes().length == 1) {
				jsonResult = (JSONResult) method.invoke(service, args.get(0));
			}
		} catch (Exception e) {
			logger.error("service抛出异常"+e.getMessage());
			jsonResult.fail("服务器内部出错");
			return jsonResult;
		}
		return jsonResult;
	}

	protected Session getSession() {
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession(true);
		return session;
	}

	public Setting getSetting() {
		return setting;
	}

	public void setSetting(Setting setting) {
		this.setting = setting;
	}

	public String parseData(Object obj){
		String result=JSONUtils.obj2json(obj);
		if(result==null){
			JSONResult rst=new JSONResult();
			rst.fail("数据解析失败");
			result=JSONUtils.obj2json(rst);
		}
		return result;
	}
}
